package com.liangsui.mss.controller.doctor;

import cn.hutool.core.date.DateUtil;
import com.liangsui.mss.constants.Constants;
import com.liangsui.mss.domain.*;
import com.liangsui.mss.dto.CareHistoryDto;
import com.liangsui.mss.dto.CareOrderFormDto;
import com.liangsui.mss.service.CareService;
import com.liangsui.mss.service.DeptService;
import com.liangsui.mss.service.PatientService;
import com.liangsui.mss.service.RegistrationService;
import com.liangsui.mss.utils.HisDateUtils;
import com.liangsui.mss.utils.IdGeneratorSnowflake;
import com.liangsui.mss.utils.ShiroSecurityUtils;
import com.liangsui.mss.vo.AjaxResult;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * CareController
 *
 * @author zhangjiawei
 * @email 1533167396@qq.com
 * @date 2022/12/8 11:18
 */
@RestController
@RequestMapping("doctor/care")
public class CareController {
    @DubboReference
    private RegistrationService registrationService; // 挂号服务层

    @DubboReference
    private PatientService patientService; // 患者服务层

    @DubboReference
    private CareService careService;  //处方、病例、开诊

    @Autowired
    private DeptService deptService;  //科室部门服务层

    /**
     * @Description: 查询待就诊的挂号信息
     * @Param: scheudlingType 就诊类型
     * @Return: AjaxResult 成功
     */
    @GetMapping("queryToBeSeenRegistration/{scheudlingType}")
    public AjaxResult queryToBeSeenRegistration(@PathVariable String scheudlingType) {
        // 获取的到当前用户的部门ID
        Long deptId = ShiroSecurityUtils.getCurrentUser().getDeptId();
        // 用户ID
        Long userId = null;
        // 设置要查询的状态,状态只能为待就诊的挂号信息
        String regStatus = Constants.REG_STATUS_1;//待就诊
        // 计算时段,当前如果是上午,则接诊时只能为上午
        String subsectionType = HisDateUtils.getCurrentTimeType();
        // 查询
        List<Registration> list = this.registrationService.queryRegistration(deptId, subsectionType, scheudlingType, regStatus, userId);
        return AjaxResult.success(list);
    }

    /**
     * @Description: 查询就诊中的挂号信息
     * @Param: scheudlingType 就诊类型
     * @Return: AjaxResult 成功
     */
    @GetMapping("queryVisitingRegistration/{scheudlingType}")
    public AjaxResult queryVisitingRegistration(@PathVariable String scheudlingType) {
        // 获取的到当前用户的部门ID
        Long deptId = ShiroSecurityUtils.getCurrentUser().getDeptId();
        // 用户ID
        Long userId = ShiroSecurityUtils.getCurrentActiveUser().getUser().getUserId();
        // 设置要查询的状态,状态只能为待就诊的挂号信息
        String regStatus = Constants.REG_STATUS_2;//就诊中
        // 查询
        List<Registration> list = this.registrationService.queryRegistration(deptId, null, scheudlingType, regStatus, userId);
        return AjaxResult.success(list);
    }

    /**
     * @Description: 查询就诊完成的挂号信息
     * @Param: scheudlingType 就诊类型
     * @Return: AjaxResult 成功
     */
    @GetMapping("queryVisitCompletedRegistration/{scheudlingType}")
    public AjaxResult queryVisitCompletedRegistration(@PathVariable String scheudlingType) {
        // 获取的到当前用户的部门ID
        Long deptId = ShiroSecurityUtils.getCurrentUser().getDeptId();
        // 用户ID
        Long userId = ShiroSecurityUtils.getCurrentActiveUser().getUser().getUserId();;
        // 设置要查询的状态,状态只能为待就诊的挂号信息
        String regStatus = Constants.REG_STATUS_3;//就诊完成
        // 查询
        List<Registration> list = this.registrationService.queryRegistration(deptId, null, scheudlingType, regStatus, userId);
        return AjaxResult.success(list);
    }

    /**
     * @Description: 接诊
     * @Param: regId 挂号单号
     * @Return: AjaxResult
     */
    @PostMapping("receivePatient/{regId}")
    public AjaxResult receivePatient(@PathVariable String regId) {
        synchronized (this) { // 防止并发,防止并发接诊问题
            // 根据挂号单ID查询挂号信息
            Registration registration = this.registrationService.queryRegistrationByRegId(regId);
            if (null == registration) {
                return AjaxResult.fail("[" + regId + "]挂号单不存在,不能接诊!");
            }
            // 只有当挂号状态RegStatus为待就诊,待就诊时才可以接诊
            if (registration.getRegStatus().equals(Constants.REG_STATUS_1)) {
                // 并发问题
                registration.setRegStatus(Constants.REG_STATUS_2);// 就诊中
                // 医生ID
                registration.setUserId(ShiroSecurityUtils.getCurrentUser().getUserId());
                // 医生姓名
                registration.setDoctorName(ShiroSecurityUtils.getCurrentUser().getUserName());
                // 修改
                return AjaxResult.toAjax(this.registrationService.updateRegistrationById(registration));
            } else {
                return AjaxResult.fail("[" + regId + "]挂号单的挂号状态不是[待就诊],不能接诊!");
            }
        }
    }

    /**
     * @Description: 根据患者ID获取患者信息
     * @Param: patientId 患者ID
     * @Return: AjaxResult
     */
    @GetMapping("getPatientAllMessageByPatientId/{patientId}")
    public AjaxResult getPatientAllMessageByPatientId(@PathVariable String patientId) {
        // 根据患者ID查询患者信息
        Patient patient = this.patientService.getPatientById(patientId);
        // 查询档案
        PatientFile patientFile = this.patientService.getPatientFileById(patientId);
        // 查询病例表
        List<CareHistory> careHistoryList = this.careService.queryCareHistoryByPatientId(patientId);
        HashMap<String, Object> maps = new HashMap<>();
        maps.put("patient", patient);
        maps.put("patientFile", patientFile);
        maps.put("careHistoryList", careHistoryList);
        return AjaxResult.success(maps);
    }

    /**
     * @Description: 保存病例信息
     * @Param: careHistoryDto
     * @Return: AjaxResult
     */
    @PostMapping("saveCareHistory")
    public AjaxResult saveCareHistory(@RequestBody CareHistoryDto careHistoryDto) {
        careHistoryDto.setUserId(ShiroSecurityUtils.getCurrentUser().getUserId());
        careHistoryDto.setUserName(ShiroSecurityUtils.getCurrentUser().getUserName());
        careHistoryDto.setDeptId(ShiroSecurityUtils.getCurrentUser().getDeptId());
        Dept dept = this.deptService.getDeptById(ShiroSecurityUtils.getCurrentUser().getDeptId());
        careHistoryDto.setDeptName(dept.getDeptName());
        careHistoryDto.setCareTime(DateUtil.date());//就诊时间
        CareHistory careHistory = this.careService.saveOrUpdateCareHistory(careHistoryDto);
        return AjaxResult.success(careHistory);
    }

    /**
     * @Description: 根据挂号ID查询病历信息
     * @Param: regId 挂号ID
     * @Return: AjaxResult
     */
    @GetMapping("getCareHistoryByRegId/{regId}")
    public AjaxResult getCareHistoryByRegId(@PathVariable String regId) {
        // 根据挂号ID查询病例信息
        CareHistory careHistory = this.careService.queryCareHistoryByRegId(regId);
        return AjaxResult.success(careHistory);
    }

    /**
     * @Description: 根据病例ID查询处方列表及详情
     * @Param: regId 病例ID
     * @Return: AjaxResult
     */
    @GetMapping("queryCareOrdersByChId/{chId}")
    public AjaxResult queryCareOrdersByChId(@PathVariable String chId) {
        // 根据病例ID查询处方信息
        List<CareOrder> careOrders = this.careService.queryCareOrdersByChId(chId);
        ArrayList<Map<String, Object>> res = new ArrayList<>();
        for (CareOrder careOrder : careOrders) {
            HashMap<String, Object> map = new HashMap<>();
            map.put("careOrder", careOrder);
            // 根据处方ID---查询处方详细信息
            List<CareOrderItem> careOrderItems = this.careService.queryCareOrdersItemsByCoId(careOrder.getCoId(), null);
            map.put("careOrderItems", careOrderItems);
            res.add(map);
        }
        return AjaxResult.success(res);
    }

    /**
     * @Description: 保存处方及详情信息
     * @Param: careOrderFormDto 封装前台传来的数据
     * @Return: AjaxResult
     */
    @PostMapping("saveCareOrderItem")
    public AjaxResult saveCareOrderItem(@RequestBody CareOrderFormDto careOrderFormDto) {
        // 根据病例ID查询病例信息
        CareHistory careHistory = this.careService.queryCareHistoryByChId(careOrderFormDto.getCareOrder().getChId());
        if (null == careHistory) {
            return AjaxResult.fail("病例ID不存在请核对后再提交!");
        }
        careOrderFormDto.getCareOrder().setCoId(IdGeneratorSnowflake.generatorIdWithProfix(Constants.ID_PREFIX_CO));
        careOrderFormDto.getCareOrder().setPatientId(careHistory.getPatientId());//患者ID
        careOrderFormDto.getCareOrder().setPatientName(careHistory.getPatientName());//患者姓名
        careOrderFormDto.getCareOrder().setUserId(ShiroSecurityUtils.getCurrentUser().getUserId());//用户ID
        careOrderFormDto.getCareOrder().setSimpleUser(ShiroSecurityUtils.getCurrentSimpleUser());//当前操作对象
        return AjaxResult.toAjax(this.careService.saveCareOrderItem(careOrderFormDto));
    }

    /**
     * @Description: 根据处方详情ID删除处方详情【只能删除未支付的】
     * @Param: itemId
     * @Return: AjaxResult
     */
    @DeleteMapping("deleteCareOrderItemById/{itemId}")
    public AjaxResult deleteCareOrderItemById(@PathVariable String itemId) {
        CareOrderItem careOrderItem = this.careService.queryCareOrderItemByItemId(itemId);
        if (null == careOrderItem) {
            return AjaxResult.fail("[" + itemId + "]处方详情ID不存在!");
        }
        if (!careOrderItem.getStatus().equals(Constants.ORDER_DETAILS_STATUS_0)) {//如果不是未支付状态
            return AjaxResult.fail("[" + itemId + "]不是未支付状态,不可以删除!");
        }
        return AjaxResult.toAjax(this.careService.deleteCareOrderItemById(itemId));
    }

    /**
     * @Description: 完成就诊
     * @Param: regId 病例ID
     * @Return: AjaxResult
     */
    @PostMapping("visitComplete/{regId}")
    public AjaxResult visitComplete(@PathVariable String regId) {
        Registration registration = this.registrationService.queryRegistrationByRegId(regId);
        if (null == registration) {
            return AjaxResult.fail("单号: [" + regId + "]挂号单号不存在,请核对后在提交!");
        }
        if (!registration.getRegStatus().equals(Constants.REG_STATUS_2)) {//未被接诊
            return AjaxResult.fail("单号: [" + regId + "]状态不是就诊中,不能完成就诊!");
        }
        // 更改挂号单的状态
        return AjaxResult.toAjax(this.careService.visitComplete(regId));
    }
}
